/*********************************************************************************
 *Author:         OnClick
 *Version:        1.0
 *UnityVersion:   2018.3.1f1
 *Date:           2019-01-28
 *Description:    IFramework
 *History:        2018.11--
*********************************************************************************/
using System.Collections.Generic;

namespace IFramework
{
	public class AStarSearcher3X :IAStarSearcher<AStarNode3X, AStarMap3X>
	{
        private AStarMap3X map;
        private List<AStarNode3X> openList;
        private List<AStarNode3X> closeList;

        public AStarSearcher3X(AStarMap3X map)
        {
            SetMap(map);
            openList = new List<AStarNode3X>();
            closeList = new List<AStarNode3X>();
            pathNodes = new List<AStarNode3X>();
        }
        public void SetMap(AStarMap3X map)
        {
            this.map = map;
        }

        private List<AStarNode3X> pathNodes;
        private AStarNode3X curNode;
        private AStarNode3X[] neighborNodes;
        public AStarNode3X[] Search(AStarNode3X start, AStarNode3X end)
        {
            map.Reset();
            openList.Clear();
            closeList.Clear();
            pathNodes.Clear();
            start.TryUpdateFCost(0, map.GetHCost(start, end), null);
            curNode = start;
            while (curNode != end)
            {
                neighborNodes = map.GetNeighborNodes(curNode);
                for (int i = 0; i < neighborNodes.Length; i++)
                {
                    if (!openList.Contains(neighborNodes[i]) && !closeList.Contains(neighborNodes[i]))
                    {
                        openList.Add(neighborNodes[i]);
                        neighborNodes[i].SetDefaultParent(curNode);
                    }
                    neighborNodes[i].TryUpdateFCost(curNode.G + map.GetHCost(curNode, neighborNodes[i]), map.GetHCost(neighborNodes[i], end), curNode);
                }
                float smallestF = float.MaxValue;
                for (int i = 0; i < openList.Count; i++)
                {
                    if (smallestF > openList[i].F)
                    {
                        smallestF = openList[i].F;
                        curNode = openList[i];
                    }
                }
                closeList.Add(curNode);
                openList.Remove(curNode);
                if (openList.Count == 0)
                {
                    return null;
                }
            }
            while (curNode.ParentNode != start)
            {
                pathNodes.Insert(0, curNode);
                curNode = curNode.ParentNode as AStarNode3X;
            }
            pathNodes.Insert(0, curNode);
            return pathNodes.ToArray();
        }
    }
}
